package com.mk.es.service.repertory.imp;



import com.mk.es.service.repertory.AbstractEsRepertoryAdapter;
import com.mk.es.service.entity.imp.ArticleEntity;
import com.mk.es.service.transport.entity.EsQueryBuilder;
import com.mk.es.service.entity.EsQueryParam;
import com.mk.es.service.transport.entity.EsQueryResult;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 *  Article ES仓库类
 */
@Repository("articleEntityEsRepertory")
public class ArticleEntityEsRepertory extends AbstractEsRepertoryAdapter<ArticleEntity> {

    public ArticleEntityEsRepertory() {
        super("demo_index", "demo_type");
    }

    /**
     * 初始化方法
     */
    @Override
    @PostConstruct
    public void init() {
        //初始化mapping
        this.putMapping();
    }

    /**
     * 添加索引类型Mapping
     * @return
     */
    @Override
    public boolean putMapping() {
        String mapping = "{ \"properties\": { \"id\": { \"type\": \"keyword\" }, \"title\": { \"analyzer\": \"ik_max_word\", \"boost\": 5, \"fields\": { \"pinyin\": { \"analyzer\": \"pinyin\", \"search_analyzer\": \"pinyin\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" } }, \"search_analyzer\": \"ik_max_word\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" }, \"subTitle\": { \"analyzer\": \"ik_max_word\", \"boost\": 5, \"fields\": { \"pinyin\": { \"analyzer\": \"pinyin\", \"search_analyzer\": \"pinyin\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" } }, \"search_analyzer\": \"ik_max_word\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" }, \"brief\": { \"analyzer\": \"ik_max_word\", \"boost\": 5, \"fields\": { \"pinyin\": { \"analyzer\": \"pinyin\", \"search_analyzer\": \"pinyin\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" } }, \"search_analyzer\": \"ik_max_word\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" }, \"source\": { \"type\": \"keyword\" }, \"author\": { \"type\": \"keyword\" }, \"tags\": { \"type\": \"keyword\" }, \"content\": { \"analyzer\": \"ik_max_word\", \"fields\": { \"pinyin\": { \"analyzer\": \"pinyin\", \"search_analyzer\": \"pinyin\", \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" } }, \"store\": false, \"term_vector\": \"with_positions_offsets\", \"type\": \"text\" }, \"createTime\": { \"type\": \"long\" } } }";
        return this.putMapping(mapping);
    }

    /**
     * 查询对应的类
     * @param param
     * @param <T>
     * @return
     */
    @Override
    public <T> EsQueryResult<T> querySearch(EsQueryParam param) {
        EsQueryBuilder esQueryBuilder = new EsQueryBuilder();
        //高亮
        esQueryBuilder.setHighlightBuilder(new HighlightBuilder().field("title").field("content").preTags(AbstractEsRepertoryAdapter.preTags).postTags(AbstractEsRepertoryAdapter.postTags));

        //bool查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(StringUtils.isNoneBlank(param.getQueryStr())){
            MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(param.getQueryStr(), "content");
            multiMatchQuery.field("title", 3.0f); //权重3
            multiMatchQuery.minimumShouldMatch("75%"); //默认在operator：or 下，这个是设置匹配精度75%
            boolQueryBuilder.must(multiMatchQuery);
        }
        // 标签
        if(StringUtils.isNoneBlank(param.getString("tags"))){
            boolQueryBuilder.filter(QueryBuilders.termsQuery("tags", param.getString("tags")));
        }
        esQueryBuilder.setQueryBuilder(boolQueryBuilder);

        //排序 01：创建时间；其它：分值；
        Map<String, SortOrder> sortMap = new HashMap<String, SortOrder>(2);
        switch (param.getString("order")==null ? "" : param.getString("order")){
            case "01": //创建时间
                sortMap.put("createTime", SortOrder.DESC);
                break;
            default: //默认排序
                break;
        }
        sortMap.put("_score", SortOrder.DESC);
        esQueryBuilder.setSortMap(sortMap);

        esQueryBuilder.setFrom( (param.getPageIndex()-1) * param.getPageSize());
        esQueryBuilder.setSize(param.getPageSize());

        return this.querySearch(esQueryBuilder);
    }

}
